local filename = "getverificationcode.lua"

local timetool = require "timetool"
local skynet = require "skynet"
local cluster = require "skynet.cluster"
local filelog =require "filelog"
local base = require "base"
local md5 = require "md5"
local configdao = require "configdao"

local httpc = require "http.httpc"
local dns = require "skynet.dns"

local redisdao = require "redisdao"
local json = require "cjson.safe"
json.encode_sparse_array(true, 1, 1)

require "pubenum"

local service = nil
local CMD = {
	service = nil
}

--验证码过期时长,默认5min后过期
local verif_code_expiratetime = 300

--验证码可重新获取的间隔时间,默认60s
local verif_code_refresh_time = 60

--是否已设置dns服务
local is_set_dns = false

--
--生成一个6位随机验证码
--
local function gen_verification_code()
    local code = ""
    local len = 6
    for i = 1,len  do
        code = code .. base.get_random(1,9)
    end
    
    return code
end

--
--通知平台服发送验证码
--
local function notice_platform_server(phonenum,verifcode)
    local sm_url = configdao.get_common_conf("sm_url") or "verqy.jyhd666.com:4321"
    local host,url = string.match(sm_url,"(.+%.%w+)/(.+)")
    local sm_key = configdao.get_common_conf("sm_key") or ""
    local recvheader = { }
    local cur_time = timetool.get_time()
    local sign = md5.sumhexa(phonenum .. cur_time .. sm_key) .. cur_time
    url = "/" .. (url or "") .. "mobile=" ..  phonenum .. "&code=" .. verifcode .. "&" .. "sign=" .. sign
    
    filelog.sys_info("---start http request---", service.rid, host, url)
    if not is_set_dns then
        skynet.pcall(httpc.dns) -- 异步dns服务，只设置一次
        is_set_dns = true
    end
	httpc.timeout = 500	    -- 超时5s
    if host == "api.daili.com" then
        host = EAPI_ADDRESS or "192.168.1.75"
    end
    local isok,status,body = skynet.pcall(httpc.post,host, url, {}, recvheader)
    filelog.sys_info("---end http request---", service.rid, status, body, host, url)
    if not is_ok then
        skynet.pcall(httpc.dns)
    end
end

--
--处理获取验证码请求
--必要参数 phonenum手机号
--
local function hanlder(msgbody, ip)

    --验证参数合法性
    if type(msgbody.phonenum) ~= "string" or string.len(msgbody.phonenum) ~= 11 then
        return {retcode = EErrCode.ERR_INVALID_REQUEST,retstr = "错误的手机号码"}
    end

    local id = msgbody.phonenum or ""
    local phonenum = msgbody.phonenum
    local first = tonumber(string.sub(phonenum,1,1))
    local high = tonumber(string.sub(phonenum,1,5))
    local low = tonumber(string.sub(phonenum,6,11))

    if first ~= 1 or not high or not low then
        return {retcode = EErrCode.ERR_INVALID_REQUEST,retstr = "错误的手机号码"}
    end

    --当前验证码不为空，表示已获取过,检验是否可以重新获得
    local cur_time = timetool.get_time()
    if service.user_list[id] and service.user_list[id].cur_verif_code and service.user_list[id].cur_verif_phonenum == phonenum then
        local last_get_time = service.user_list[id].cur_verif_code_expiratetime - verif_code_expiratetime
        local dur_time = cur_time - last_get_time
        if dur_time <= verif_code_refresh_time then
            return {retcode = EErrCode.ERR_INVALID_REQUEST,retstr = "操作过于频繁，请稍后重试！"}
        end
    end
	
    service.user_list[id] = service.user_list[id] or {}
    --当前认证手机号
    service.user_list[id].cur_verif_phonenum = phonenum
    --当前验证码
    service.user_list[id].cur_verif_code = gen_verification_code()
    --验证码过期时间
    service.user_list[id].cur_verif_code_expiratetime = cur_time + verif_code_expiratetime

    --通知平台服发送验证码
    skynet.fork(notice_platform_server,phonenum,service.user_list[id].cur_verif_code)

    --保存验证码
    local key = id
    local variable = {
        cur_verif_phonenum = service.user_list[id].cur_verif_phonenum,
        cur_verif_code = service.user_list[id].cur_verif_code,
        cur_verif_code_expiratetime = service.user_list[id].cur_verif_code_expiratetime,
    }
    if key then
        redisdao.query_data(".gmmqredis", "set", key .. ":cur_verifinfo", json.encode(variable))
    end

    --记录获取验证码的ip
    if ip and ip ~= "" then
        service.vercode_ips[ip] = cur_time
    end

	return { }
end

--处理获取验证码
function CMD.process(session, source, msgbody, ip)
    if not service then
		service = CMD.service
	end

    --跳过内网ip
    local ip1, ip2, ip3, ip4 = string.match(ip or "", "(%d+).(%d+).(%d+).(%d+)")
    if ip == "127.0.0.1" or (ip1 == "192" and ip2 == "168") then
        ip = nil
    end

    --1个ip 1分钟内只能获取一次验证码
    local now = timetool.get_time()
    if ip and service.vercode_ips[ip] and (now - service.vercode_ips[ip]) <= 60 then
        local resp = {retcode = EErrCode.ERR_INVALID_REQUEST,retstr = "同IP一分钟内只能获取一次验证码"}
        skynet.retpack(resp)
        return
    end

    --每隔20min清理一次ip列表
    if now % 1200 == 0 then
        for k,v in pairs(service.vercode_ips) do
            if (now - v) > 60 then
                service.vercode_ips[k] = nil
            end 
        end
    end

    skynet.retpack(hanlder(msgbody, ip))
end

return CMD